package com.lebang.service;

import com.alibaba.fastjson.JSON;
import com.lebang.component.RedisClient;
import com.lebang.component.UMengPushComponent;
import com.lebang.domain.*;
import com.lebang.entity.RequestHeaders;
import com.lebang.example.MemberClickRouseExample;
import com.lebang.example.MemberClidkRouseRecordExample;
import com.lebang.mapper.*;
import com.lebang.model.MoneyCategory;
import com.lebang.model.TaskInitModel;
import com.lebang.model.Whether;
import com.lebang.model.enums.OsVersionEnum;
import com.lebang.model.enums.buss.*;
import com.lebang.service.buss.MemberTradeService;
import com.lebangweb.common.TextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Author: hwq
 * @Date: 2020/2/24 15:06
 * @Version 1.0
 */
@Service
public class CpaService {
    public static final String ZY_DATA = "ZY_CPA";
    public static final String ZY_ROUSE_DETAIL = "ZY_ROUSE_DETAIL_AMOUNT";
    public static final Integer EVENT_TIME = 1200;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private DownloadMemberRecordMapper recordMapper;
    @Autowired
    private MemberTradeService tradeService;
    @Autowired
    private UMengPushComponent uMengPushComponent;
    @Autowired
    private MemberNoticeService noticeService;
    @Autowired
    private PointService pointService;
    @Autowired
    private TaskRouseMapper rouseMapper;
    @Autowired
    private TaskRouseDetailMapper taskRouseDetailMapper;
    @Autowired
    private MemberClidkRouseRecordMapper clidkRouseRecordMapper;
    @Autowired
    private MemberClickRouseMapper clickRouseMapper;
    private static final String DOWN_APP_RECORD_EXPIRE = "DOWN_APP_RECORD_EXPIRE:";
    @Autowired
    private LbbMemberRecordMapper lbbMemberRecordMapper;
    @Autowired
    private LbbMemberMapper lbbMemberMapper;
    public String getExpireKey() {
        return DOWN_APP_RECORD_EXPIRE;
    }

    public void pushByDetail(DownloadMemberRecord record, RequestHeaders requsetHeader,int category) {
        record.setCategory(category);
        record.setModifyTime(LocalDateTime.now());
        record.setStatus(DownStatus.SUCCESS.getIndex());
        if (record.getRewardType().equals(RewardTypeUscan.Cash.getIndex())) {
            //金钱
            tradeService.addMoney(record.getMemberId(), record.getMoney(),
                    "恭喜完成任务", "完成每日必赚获得" +
                            new BigDecimal(record.getMoney()).divide(new BigDecimal(100),
                                    2, BigDecimal.ROUND_DOWN) + "元", "",
                    requsetHeader, JSON.toJSONString(record), new MoneyCategory(Whether.YES,TaskCategory.CSJ_ZXR));
            noticeService.addNoticeAndPush("恭喜完成任务", "完成每日必赚获得" + new BigDecimal(record.getMoney()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN) + "元", record.getMemberId(), requsetHeader);
        } else {
            //金币
            pointService.addPointBySdk(record.getMemberId(), record.getMoney(),
                    TaskCategory.CSJ_ZXR, "完成每日必赚获得" + record.getMoney() + "金币", requsetHeader);
            noticeService.addNoticeAndPush("恭喜完成任务", "完成每日必赚获得" + record.getMoney() + "金币", record.getMemberId(), requsetHeader);
        }
        TaskRouseDetail detail = taskRouseDetailMapper.selectByPrimaryKey(record.getRouseDetailId().longValue());
        taskRouseDetailMapper.addSuccess(detail.getId().intValue());
        this.recordDel(record.getId());
        //开启了签到
        if (detail.getIsClick().equals(Whether.YES.getDbIndex())) {
            clickInit(record, detail.getIcon(), detail.getStrategyId());
        }
        recordMapper.updateByPrimaryKeySelective(record);
    }

    /**
     * 加载签到数据
     *
     * @param record
     */
    public void clickInit(DownloadMemberRecord record, String icon, Integer id) {
        //根据包名唯一
        List<Integer> integers=new ArrayList<>();
        integers.add(1);
        integers.add(-1);
        MemberClickRouseExample example = new MemberClickRouseExample();
        example.createCriteria()
                .andStatusIn(integers)
                .andHasDeletedEqualTo(Whether.NO.getDbIndex())
                .andPkgNameEqualTo(record.getPkgName())
                .andMemberIdEqualTo(record.getMemberId())
        .andRouseDetailIdEqualTo(record.getRouseDetailId());
        long count = clickRouseMapper.countByExample(example);
        //不存在才添加数据
        if (count == 0) {
            MemberClickRouse clickRouse = new MemberClickRouse();
            clickRouse.setCreateTime(LocalDateTime.now());
            clickRouse.setModifyTime(LocalDateTime.now());
            clickRouse.setHasDeleted(Whether.NO.getDbIndex());
            clickRouse.setPkgName(record.getPkgName());
            clickRouse.setLastTime(LocalDateTime.now());
            clickRouse.setCount(0);
            List<String> list = new ArrayList<>();
            clickRouse.setClickJson(JSON.toJSONString(list));
            clickRouse.setStatus(1);
            clickRouse.setMemberId(record.getMemberId());
            clickRouse.setAppName(record.getAppName());
            clickRouse.setIcon(icon);
            clickRouse.setWaitTime(record.getTime());
            clickRouse.setRouseId(rouseMapper.selectByKey(record.getSdkKey()).getId());
            if (!TextUtil.isEmpty(record.getRouseDetailId())) {
                clickRouse.setRouseDetailId(record.getRouseDetailId());
                clickRouse.setStrategyId(id);
            }
            clickRouseMapper.insertSelective(clickRouse);
        }
    }

    /**
     * 领取任务 -- 自营数据源
     *
     * @param memberId
     * @param header
     * @return
     */
    public DownloadMemberRecord pull(String memberId, RequestHeaders header,  TaskRouseDetail detail) {
        if(detail==null){
            return null;
        }
        DownloadMemberRecord record = new DownloadMemberRecord();
        LocalDateTime time = lbbMemberMapper.selectCreaTimeByMemberId(memberId);
        if (time != null) {
            if (LocalDate.now().equals(time.toLocalDate())) {
                record.setIsNewMember(Whether.YES.getDbIndex());
            } else {
                record.setIsNewMember(Whether.NO.getDbIndex());
            }
        } else {
            record.setIsNewMember(-1);
        }
        //自营数据源
        record.setVersion(header.getVersion());
        record.setRouseDetailId(detail.getId().intValue());
        record.setPkgName(detail.getPkgName());
        record.setAppName(detail.getAppName());
        //下载型
        record.setType(DownCategory.DOWN_LOAD.getIndex());
        record.setRewardType(detail.getRewardType());
        if (record.getRewardType().equals(RewardTypeUscan.Cash.getIndex())) {
            record.setMoney(detail.getRewardMoney());
        } else {
            record.setMoney(detail.getRewardPoint());
        }
        record.setTime(detail.getRouseTime());
        this.addLook(detail, memberId);
        this.taskAmountSubtract(detail.getId());


        record.setCreateTime(LocalDateTime.now());
        record.setHasDeleted(Whether.NO.getDbIndex());
        record.setCategory(null);
        record.setMemberId(memberId);
        record.setSdkKey(getZyData());
        record.setStatus(DownStatus.WAIT_PUSH.getIndex());
        record.setUa(header.getUa());
        record.setImei(header.getImei());
        record.setIpAddress(header.getIpAddr());
        record.setAppStore(header.getAppStore());
        recordMapper.insertSelective(record);
        //加一个20分钟以后的事件
        this.recordAdd(record.getId());
        return record;
    }

    /**
     * 取自营数据源
     *
     * @param memberId
     * @param header
     * @return
     */
    public TaskRouseDetail getDetailByZy(String memberId, RequestHeaders header) {
        List<TaskRouseDetail> longs = taskRouseDetailMapper.selectIdAllList(header.getVersion(), header.getAppStore());
        Collections.shuffle(longs);
        return this.getAllDetail(longs, memberId,header);
    }

    /**
     * 取全局优先自营的数据源
     *
     * @param memberId
     * @return
     */
    public TaskRouseDetail getFirst(String memberId, RequestHeaders header) {
        List<TaskRouseDetail> longs = taskRouseDetailMapper.selectFirstIdList(header.getVersion(), header.getAppStore());
        return this.getUnLookDetail(longs, memberId);
    }

    /**
     * 取全部
     *
     * @param longs
     * @param memberId
     * @return
     */
    public TaskRouseDetail getAllDetail(List<TaskRouseDetail> longs, String memberId, RequestHeaders header) {
        if (longs.size() > 0) {
            for (TaskRouseDetail ids : longs) {
                //区分安卓10
                if(ids.getOvsType().equals(OsVersionEnum.ANDROID_10.getIndex())){
                 Integer osv=Integer.parseInt(header.getOsVersion());
                 if(osv<=28){
                     continue;
                 }
                }
                if(ids.getOvsType().equals(OsVersionEnum.ANDROID_1_9.getIndex())){
                    Integer osv=Integer.parseInt(header.getOsVersion());
                    if(osv>28){
                        continue;
                    }
                }
                //查库存
                int stockCount=this.getCpaAmount(ids.getId());
                if(stockCount<=0){
                    continue;
                }
                int i = recordMapper.selectByDetailIdAndMemberId(ids.getId(), memberId);
                if (i > 0) {
                    continue;
                }
                //过滤截图任务
                if (ids.getOpenFiter().equals(Whether.YES.getDbIndex())) {
                    int k = lbbMemberRecordMapper.checkRecordStatus(memberId, ids.getFiterKeywords(), TaskStatus.CheckSuccess.name());
                    if (k > 0) {
                        continue;
                    }
                }
                return ids;
            }
        }
        return null;
    }
    /**
     * 获取任务量
     */
    public Integer getCpaAmount(long id) {
        String amount = redisClient.hget(ZY_ROUSE_DETAIL, String.valueOf(id));
        if (amount == null) {
            return 0;
        }
        try {
            return Integer.parseInt(amount);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 取用户今天没浏览过的任务和没做过的任务
     *
     * @param longs
     * @param memberId
     * @return
     */
    public TaskRouseDetail getUnLookDetail(List<TaskRouseDetail> longs, String memberId) {
        if (longs.size() > 0) {
            for (TaskRouseDetail ids : longs) {
                int stockCount=this.getCpaAmount(ids.getId());
                if(stockCount<=0){
                    continue;
                }
                int i = recordMapper.selectByDetailIdAndMemberId(ids.getId(), memberId);
                //过滤截图任务
                if (ids.getOpenFiter().equals(Whether.YES.getDbIndex())) {
                    int k = lbbMemberRecordMapper.checkRecordStatus(memberId, ids.getFiterKeywords(), TaskStatus.CheckSuccess.name());
                    if (k > 0) {
                        continue;
                    }
                }

                if (i > 0) {
                    continue;
                }/* else {
                    String str = redisClient.get(getKeyByLook() + memberId);
                    if (str == null) {
                        return ids;
                    } else {
                        List<Long> longs1 = JSON.parseArray(str, Long.class);
                        if (longs1.contains(ids.getId())) {
                            continue;
                        } else {
                            return ids;
                        }
                    }
                }*/
            }
        }
        return null;
    }

    public TaskRouse selectZyRouse() {
        return rouseMapper.selectByKey(ZY_DATA);
    }


    /**
     * 添加浏览记录
     *
     * @param detail
     * @param memberId
     */
    private void addLook(TaskRouseDetail detail, String memberId) {
        String str = redisClient.get(getKeyByLook() + memberId);
        List<Long> longs;
        if (str == null) {
            longs = new ArrayList<>();
            longs.add(detail.getId());
        } else {
            longs = JSON.parseArray(str, Long.class);
            if (!longs.contains(detail.getId())) {
                longs.add(detail.getId());
            }
        }
        redisClient.setex(getKeyByLook() + memberId, 86400, JSON.toJSONString(longs));
    }


    private static final String MEMBER_LOOK_HISTORY = "member_look_history:";

    public String getKeyByLook() {
        LocalDate date = LocalDate.now();
        return MEMBER_LOOK_HISTORY + date.format(DateTimeFormatter.ISO_DATE);
    }

    /**
     * 自营数据源的签到策略
     *
     * @param s
     * @param days
     * @param now
     * @return
     */
    public boolean clickInitByDetail(MemberClickRouse s, int days, LocalDate now, List<ClickStrategyDetail> rouseClicks) {
        if (TextUtil.isEmpty(s.getRouseDetailId())) {
            return false;
        }
        for (ClickStrategyDetail next : rouseClicks) {
            if (next.getDayCount() >= days) {
                //今天签到的
                if (next.getDayCount() == days) {
                    //   今天签过就到明天
                    if (this.checkClickByMemberId(s.getMemberId(), s.getId(), now)) {
                        //明天可签就返回 不然删除
                        for (ClickStrategyDetail vo : rouseClicks) {
                            if (vo.getDayCount() >= (days + 1)) {
                                s.setStatus(2);
                                if (vo.getRewardType().equals(RewardTypeUscan.Cash.getIndex())) {
                                    s.setWorth(vo.getDayMoney());
                                } else {
                                    s.setWorth(vo.getDayPoint());
                                }
                                s.setClickDay(s.getCreateTime().plusDays(vo.getDayCount()).getDayOfMonth());
                                return true;
                            }
                        }
                        return false;
                    }
                    s.setClickDay(0);
                } else {
//                    //明天签到的-
//                    if (next.getDayCount() == days + 1) {
//                        s.setStatus(2);
//                        s.setClickTime(s.getCreateTime().plusDays(next.getDayCount()).toLocalDate());
//                    } else {
//                        //其他签到的 隐藏
//                        return false;
//                    }
//                    s.setClickDay(s.getCreateTime().plusDays(next.getDayCount()).getDayOfMonth());
                    s.setStatus(2);
                    s.setClickDay(s.getCreateTime().plusDays(next.getDayCount()).getDayOfMonth());

                }
                if (next.getRewardType().equals(RewardTypeUscan.Cash.getIndex())) {
                    s.setWorth(next.getDayMoney());
                } else {
                    s.setWorth(next.getDayPoint());
                }
                return true;
            }
        }
        return false;
    }

    /**
     * 验证用户哪天有没有签到过
     *
     * @param memberId
     * @return
     */
    public boolean checkClickByMemberId(String memberId, long rouseId, LocalDate date) {
        MemberClidkRouseRecordExample example = new MemberClidkRouseRecordExample();
        example.createCriteria().andClcikRouseIdEqualTo(rouseId)
                .andMemberIdEqualTo(memberId)
                .andClickTimeEqualTo(date);
        return clidkRouseRecordMapper.countByExample(example) > 0;
    }

    private int getClickMoneyByRouseClick(ClickStrategyDetail po) {
        if (po.getRewardType() > 0) {
            return po.getDayMoney();
        } else {
            return po.getDayPoint();
        }
    }

    /**
     * 修改签到数据 并且奖励
     *
     * @param now
     * @param vo
     * @param strings
     */
    public void clickAddByDetail(String now, MemberClickRouse vo, List<String> strings, RequestHeaders header,
                                 ClickStrategyDetail po,int days,int star) {
        MemberClidkRouseRecord record = new MemberClidkRouseRecord();
        strings.add(now);
        vo.setCount(vo.getCount() + 1);
        vo.setLastTime(LocalDateTime.now());
        vo.setClickJson(JSON.toJSONString(strings));
        record.setUa(header.getUa());
        record.setImei(header.getImei());
        record.setIpAddress(header.getIpAddr());
        record.setAppStore(header.getAppStore());
        record.setRewardType(po.getRewardType());
        record.setDays(star);
        record.setDayCount(days);
        clickRouseMapper.updateByPrimaryKeySelective(vo);
        int money = this.getClickMoneyByRouseClick(po);
        if (po.getRewardType().equals(RewardTypeUscan.Cash.getIndex())) {
            //金钱
            tradeService.addMoney(vo.getMemberId(), money,
                    "恭喜完成任务", "完成每日必赚签到"
                            + new BigDecimal(money).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)
                            + "元", "", header, "", new MoneyCategory(Whether.YES,TaskCategory.EARN_CLICK));
            uMengPushComponent.sendNoRead("恭喜完成任务", "完成每日必赚获得" + new BigDecimal(money).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN) + "元", vo.getMemberId());
            noticeService.addNotice("恭喜完成任务", "完成每日必赚获得" + new BigDecimal(money).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN) + "元", vo.getMemberId(), header);
            record.setWorth(money);
        } else {
            //金币
            pointService.addPointBySdk(vo.getMemberId(), money, TaskCategory.EARN_CLICK, "完成每日必赚签到" + money + "金币", header);
            uMengPushComponent.sendNoRead("恭喜完成任务", "完成每日必赚签到" + money + "金币", vo.getMemberId());
            noticeService.addNotice("恭喜完成任务", "完成每日必赚签到" + money + "金币", vo.getMemberId(), header);
            record.setWorth(money);
        }
        record.setCreateTime(LocalDateTime.now());
        record.setMemberId(vo.getMemberId());
        record.setClickTime(LocalDate.now());
        record.setClcikRouseId(vo.getId());
        record.setRouseDetailId(vo.getRouseDetailId());
        TaskRouse rouse = rouseMapper.selectByPrimaryKey(vo.getRouseId());
        record.setRouseId(rouse.getId().intValue());
        record.setDayCount(po.getDayCount());
        clidkRouseRecordMapper.insertSelective(record);
    }



    public String getZyData() {
        return ZY_DATA;
    }


    /**
     * 删除任务记录
     *
     * @param recordId 记录ID
     */

    public void recordDel(Long recordId) {
        redisClient.del(DOWN_APP_RECORD_EXPIRE + recordId);
    }


    /**
     * 设置任务过期监听事件
     */
    public void recordAdd(Long i) {
        redisClient.setex(DOWN_APP_RECORD_EXPIRE + i.toString(), EVENT_TIME, "1");
    }

    /**
     * 任务每日量+1
     */
    public boolean taskAmountAdd( long id) {
        return redisClient.hincrBy(ZY_ROUSE_DETAIL, String.valueOf(id), 1) > 0;
    }

    /**
     * 任务每日量-1
     */
    public boolean taskAmountSubtract(long id) {
        return redisClient.hincrBy(ZY_ROUSE_DETAIL, String.valueOf(id), -1) > 0;
    }


    /**
     * 加载单个任务
     *
     * @param model
     * @return
     */
    public boolean taskInitByTaskModel(TaskInitModel model) {
        try {
            int count;
            if (model.getTotal() == 0) {
                model.setTotal(99999999);
            }
            if (model.getAmount() == 0) {
                model.setAmount(9999);
            }
            if (model.getSuccessTotal() >= model.getTotal()) {
                count = 0;
            } else {
                if (model.getTotal() - model.getSuccessTotal() >= model.getAmount()) {
                    count = model.getAmount() - model.getTodayTotal();
                } else {
                    count = model.getTotal() - model.getSuccessTotal();
                }
            }
            //获取当日待提交任务也计入每日量
            int o = recordMapper.getByStatus(model.getId(),DownStatus.WAIT_PUSH.getIndex(),ZY_DATA);

            count = count - o;
            if (count < 0) {
                count = 0;
            }
            redisClient.hset(ZY_ROUSE_DETAIL, String.valueOf(model.getId()), Integer.toString(count));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public void fail(DownloadMemberRecord record) {
        this.taskAmountAdd(record.getRouseDetailId());
        record.setStatus(DownStatus.RELSE.getIndex());
        record.setReleaseTime(LocalDateTime.now());
        recordMapper.updateByPrimaryKeySelective(record);
        taskRouseDetailMapper.addFail(record.getRouseDetailId());
    }


}
